/*
 * DialogRules
 * Version: 0.1
 * Date: 2009-03-01
 * Author: gp08-nhn
 */

package keyboardhero;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import keyboardhero.Util.*;

final class DialogAbout extends AbstractDialog {
	
	//-------------------- VARIABLES --------------------
	
	private static final long serialVersionUID = 5983805921440757485L;
	
	private static DialogAbout instance = null; // used only for debugging
	
	private final JLabel textLabel, iconLabel;
	private final JTextArea textArea;
	private boolean needLabelSetup = true;
	
	//-------------------- CORE FUNCTIONS --------------------
	
	DialogAbout(JFrame frame) {
		super(frame, null, "about", true);
		setMinimumSize(new Dimension(400, 300));
		setTitle(Util.getMsgMnemonic("Menu_About") + " - " + KeyboardHero.APP_TITLE);
		
		final Container contentPane;
		JPanel panel;
		
		(contentPane = getContentPane()).add(panel = new JPanel(), BorderLayout.NORTH);
		
		panel.setBorder(new EmptyBorder(10, 10, 10, 10));
		panel.setLayout(new BorderLayout());
		panel.add(iconLabel = new JLabel(UIManager.getIcon("OptionPane.informationIcon")), BorderLayout.WEST);
		iconLabel.setBorder(new EmptyBorder(0, 0, 0, 20));
		panel.add(textLabel = new JLabel(), BorderLayout.CENTER);
		
		JButton bn;
		panel.add(bn = new JButton(new ScaledIcon(new ImageIcon(Util.TOOLKIT.getImage(Util.getURL("Logo.png"))), 139, 80, Image.SCALE_SMOOTH)), BorderLayout.EAST);
		bn.setMargin(new Insets(0, 0, 0, 0));
		bn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				final Rectangle dialogBounds = getBounds();
				
				Rectangle bounds = null;
				int maxIntersection = -1;
				for(final GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
					final Rectangle deviceBounds = gd.getDefaultConfiguration().getBounds();
					final Rectangle intersection = dialogBounds.intersection(deviceBounds);
					int intersectionValue = intersection.width * intersection.height;
					if(intersectionValue > maxIntersection) {
						maxIntersection = intersectionValue;
						bounds = deviceBounds;
						break;
					}
				}
				GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds();
				
				try {
					DialogAboutGLLogo.open(bounds);
				} catch(Throwable ex) {
					if(Util.getDebugLevel() > 30) ex.printStackTrace();
					
					DialogAboutNormalLogo.open(bounds);
				}
			}
		});
		
		textArea = new JTextArea(KeyboardHero.APP_LICENSE);
		textArea.setEditable(false);
		textArea.setBackground(new Color(UIManager.getColor("Panel.background").getRGB()));
		textArea.setBorder(new EmptyBorder(10, 10, 10, 10));
		textArea.setFont(new Font(Font.MONOSPACED, 0, 12));
		textArea.setLineWrap(true);
		textArea.setWrapStyleWord(true);
		textArea.setAutoscrolls(true);
		
		contentPane.add(new JScrollPane(textArea), BorderLayout.CENTER);
		
		contentPane.add(panel = new JPanel(), BorderLayout.SOUTH);
		
		if(Util.DESKTOP != null && Util.DESKTOP.isSupported(Desktop.Action.OPEN)) {
			final JButton button;
			final JPanel spanel;
			panel.setLayout(new BorderLayout());
			panel.add(spanel = new JPanel(), BorderLayout.EAST);
			spanel.add(button = new JButton());
			Util.updateButtonText(button, "WholeLicense");
			button.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					try {
						Util.DESKTOP.open(new File(Util.getURL("LICENSE.txt").toURI()));
					} catch(NullPointerException ex) {
						Util.error(Util.getMsg("Err_CantOpenLicense"), Util.getMsg("Err_FileNotFound"));
					} catch(Exception ex) {
						Util.error(Util.getMsg("Err_CantOpenLicense"), ex.getLocalizedMessage());
					}
				}
			});
			
			panel.add(panel = new JPanel(), BorderLayout.CENTER);
		}
		
		panel.setLayout(new FlowLayout());
		
		JButton bnOk;
		panel.add(bnOk = new JButton(Util.getMsgMnemonic("OK")));
		bnOk.setMnemonic(Util.getLastMnemonic());
		bnOk.setDisplayedMnemonicIndex(Util.getLastMnemonicIndex());
		bnOk.setName("OK");
		bnOk.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				close();
			} // end method
		} // end class
		);
		getRootPane().setDefaultButton(bnOk);
		
		instance = this;
	}
	
	private void labelSetup() {
		final String cache;
		
		if(!((cache = Util.getMsg("NameOfTranslator").trim().toLowerCase()).equals("!nameoftranslator!") || cache.startsWith("please type here your name"))) {
			KeyboardHero.APP_TRANSLATORS.add(cache);
		}
		
		final StringBuffer str = new StringBuffer();
		
		str.append("<html><b><u>");
		str.append(KeyboardHero.APP_NAME);
		str.append("</u></b><br /><i>");
		str.append(Util.getMsg("Version"));
		str.append(":</i> ");
		str.append(KeyboardHero.APP_VERSION);
		str.append("<br /><br /><i>");
		str.append(Util.getMsg("Authors"));
		str.append(":</i><br />");
		str.append(KeyboardHero.APP_AUTHORS);
		
		if(!KeyboardHero.APP_TRANSLATORS.isEmpty()) {
			str.append("<br /><br /><i>");
			str.append(Util.getMsg("ThanksForTranslating"));
			str.append(":</i> ");
			boolean first = true;
			for(String translator : KeyboardHero.APP_TRANSLATORS) {
				if(first) {
					first = false;
				} else {
					str.append(", ");
				}
				str.append(translator);
			}
		}
		
		str.append("<br /></html>");
		
		textLabel.setText(str.toString());
		
		needLabelSetup = false;
	}
	
	//-------------------- OVERRIDING FUNCTIONS --------------------
	
	@Override
	protected void open() {
		if(needLabelSetup) labelSetup();
		super.open();
	} // end method
	
	@Override
	protected void updateUI() {
		super.updateUI();
		textArea.setBackground(new Color(UIManager.getColor("Panel.background").getRGB()));
		iconLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
	}
	
	@Override
	protected void updateTexts() {
		super.updateTexts();
		needLabelSetup = true;
	}
	
	@Override
	protected AbstractDialog getNewInstance(JFrame frame) {
		return new DialogAbout(frame);
	}
	
	//-------------------- DEBUGGING FUNCTIONS --------------------
	
	/**
	 * Creates a string containing the most important information about the game. This method is
	 * used only for debugging and testing purposes.
	 * 
	 * @return the created string.
	 */
	static String getString() { //$SUP-MCP$
		return "DialogAbout(visible=" + instance.isVisible() + "; location=" + instance.getLocationOnScreen() + "; bounds=" + instance.getBounds() + ")";
	} // end method
	
	/**
	 * This method serves security purposes. Provides an integrity string that will be checked by
	 * the {@link Connection#integrityCheck()} method; thus the application can only be altered if
	 * the source is known. Every class in the {@link keyboardhero} package has an integrity string.
	 * 
	 * @return the string of this class used for integrity checking.
	 */
	static String getIntegrityString() {
		return "U!asdf4jk3++asdfas$";
	} // end method
	
	/**
	 * The tester object of this class. It provides a debugging menu and unit tests for this class.
	 * Its only purpose is debugging or testing.
	 */
	final static Tester TESTER = new Tester("DialogAbout", new String[] {"getString()"} /* end initialization */) { //$SUP-PPA$
		void menu(int choice) throws Exception {
			switch(choice) {
				case 5:
					System.out.println(getString());
					break;
				default:
					baseMenu(choice);
					break;
			} // end switch
		} // end method
		
		void runUnitTests() throws Exception {
			higherTestStart("DialogAbout");
			
			testEq("getIntegrityString()", "U!asdf4jk3++asdfas$", DialogAbout.getIntegrityString());
			
			higherTestEnd();
		} // end method
	}; // end class
	
	/**
	 * Starts the class's developing menu. If this build is a developer's one it starts the
	 * application in a normal way with the exception that it starts the debugging tool for this
	 * class as well; otherwise exits with an error message.
	 * 
	 * @param args
	 *            the arguments given to the program.
	 * @see KeyboardHero#startApp()
	 */
	public static void main(String[] args) {
		Tester.mainer(args, TESTER);
	} // end method
}
